﻿using System;
using UnityEngine;

namespace Ning.Preferences
{
    /// <summary>
    /// Interface that is used for communicating with third party assets.
    /// </summary>
    public  abstract class IPreferences
    {
        /// <summary>
        /// For the similar method in PlayerPrefs.
        /// </summary>
        public abstract void DeleteAll();

        /// <summary>
        /// For the similar method in PlayerPrefs.
        /// </summary>
        public abstract void DeleteKey(string key);

        /// <summary>
        /// For the similar method in PlayerPrefs.
        /// </summary>
        public abstract float GetFloat(string key, float defaultValue = 0.0f);

        /// <summary>
        /// For the similar method in PlayerPrefs.
        /// </summary>
        public abstract int GetInt(string key, int defaultValue = 0);

        /// <summary>
        /// For the similar method in PlayerPrefs.
        /// </summary>
        public abstract string GetString(string key, string defaultValue = "");

        /// <summary>
        /// Get boolean preferences
        /// </summary>
        public abstract bool GetBool(string key, bool defaultValue = false);

        /// <summary>
        /// Get Vector2 preferences
        /// </summary>
        public abstract Vector2? GetVector2(string key, Vector2? defaultValue = null);

        /// <summary>
        /// Get Vector3 preferences
        /// </summary>
        public abstract Vector3? GetVector3(string key, Vector3? defaultValue = null);

        /// <summary>
        /// Get Color preferences
        /// </summary>
        public abstract Color? GetColor(string key, Color? defaultValue = null);

        /// <summary>
        /// For the similar method in PlayerPrefs.
        /// </summary>
        public abstract bool HasKey(string key);

        /// <summary>
        /// For the similar method in PlayerPrefs.
        /// </summary>
        public abstract void Save();

        /// <summary>
        /// For the similar method in PlayerPrefs.
        /// </summary>
        public abstract void SetFloat(string key, float value);

        /// <summary>
        /// For the similar method in PlayerPrefs.
        /// </summary>
        public abstract void SetInt(string key, int value);

        /// <summary>
        /// For the similar method in PlayerPrefs.
        /// </summary>
        public abstract void SetString(string key, string value);

        /// <summary>
        /// Set boolean preferences
        /// </summary>
        public abstract void SetBool(string key, bool value);

        /// <summary>
        /// Set Vector2 preferences
        /// </summary>
        public abstract void SetVector2(string key, Vector2? value);

        /// <summary>
        /// Set Vector3 preferences
        /// </summary>
        public abstract void SetVector3(string key, Vector3? value);

        /// <summary>
        /// Set Color preferences
        /// </summary>
        public abstract void SetColor(string key, Color? value);

        public Vector3? StringToVector3(string value)
        {
            var data = SplitData(value);
            if (data.Length != 3)
            {
                return null;
            }
            else
            {
                return new Vector3(
                    float.Parse(string.IsNullOrEmpty(data[0]) ? "0" : data[0]),
                    float.Parse(string.IsNullOrEmpty(data[0]) ? "0" : data[1]),
                    float.Parse(string.IsNullOrEmpty(data[0]) ? "0" : data[2])
                    );
            }
        }

        public Vector2? StringToVector2(string value)
        {
            return StringToVector3(value);
        }

        public Color? StringToColor(string value)
        {
            var data = SplitData(value);
            if (data.Length != 4)
            {
                return null;
            }
            else
            {
                return new Color(
                    float.Parse(string.IsNullOrEmpty(data[0]) ? "0" : data[0]),
                    float.Parse(string.IsNullOrEmpty(data[0]) ? "0" : data[1]),
                    float.Parse(string.IsNullOrEmpty(data[0]) ? "0" : data[2]),
                    float.Parse(string.IsNullOrEmpty(data[0]) ? "0" : data[3])
                    );
            }
        }

        public string Vector3ToString(Vector3? value)
        {
            return value==null?"":string.Format("{0},{1},{2}", value.Value.x, value.Value.y, value.Value.z);
        }

        public string Vector2ToString(Vector2? value)
        {
            return value == null ? "" : string.Format("{0},{1}", value.Value.x, value.Value.y);
        }

        public string ColorToString(Color? value)
        {
            return value == null ? "" : string.Format("{0},{1},{2},{3}", value.Value.r, value.Value.g, value.Value.b, value.Value.a);
        }

        public string[] SplitData(string value)
        {
            return value.Split(',');
        }
    }
}

